﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TuyennvLibrary.ServerApi.Controllers;
using Newtonsoft.Json.Linq;
using TuyennvLibrary.Attributes;
using TuyennvLibrary.Reflection;
using TuyennvLibrary.ServerApi.ClassApi;
using TuyennvLibrary.ServerApi.Sms;
using TuyennvLibrary.ServerApi.Models;
namespace TuyennvLibrary.ServerApi.Util
{
    public static class ApiUtilities
    {        
        public static DescriptionClass getDescriptionClass(Type cls)
        {
            List<AttributeDescriptionClass> listAttribute;
            DescriptionClass description = new DescriptionClass();
            description.Name = cls.Name;
            AttributeDescriptionClass[] attributes = (AttributeDescriptionClass[])Attribute.GetCustomAttributes(cls, typeof(AttributeDescriptionClass));
            //LogicalMethodInfo myLogicalMethodInfo =
            //  (LogicalMethodInfo.Create(new MethodInfo[] { method },
            //                            LogicalMethodTypes.Sync))[0];
            //ICustomAttributeProvider myCustomAttributeProvider = myLogicalMethodInfo.CustomAttributeProvider;
            //bool isdefined = myCustomAttributeProvider.IsDefined(typeof(AttributeDescriptionMethod), true);
            if (attributes != null && attributes.Length > 0)
            {
                listAttribute = new List<AttributeDescriptionClass>();
                //object[] attributes = myCustomAttributeProvider.GetCustomAttributes(true);
                foreach (AttributeDescriptionClass attribute in attributes)
                {
                    if (!listAttribute.Contains(attribute))
                    {
                        listAttribute.Add(attribute);
                    }
                }
                listAttribute.Sort();
                foreach (AttributeDescriptionClass attribute in listAttribute)
                {
                    description.Description += string.Format("{0}<br />", attribute.ToString());
                }

            }
            return description;
        }
        public static List<DescriptionClass> getListDescriptionClass(string pathDll, int typeClass)
        {
            string result = string.Empty;
            List<DescriptionClass> listDescription = new List<DescriptionClass>();
            //Xac dinh kieu cua class
            Assembly dll = null;
            List<Type> listType = new List<Type>();
            try
            {
                if (!string.IsNullOrEmpty(pathDll))
                {
                    dll = Assembly.LoadFile(pathDll);
                }
                else
                {
                    dll = Assembly.GetExecutingAssembly();
                }
                if (typeClass == 1)
                {
                    foreach (Type type in dll.GetTypes())
                    {
                        if (type.Name.ToLower().EndsWith("api"))
                        {
                            bool CheckInheritBaseApi = IsInheritBaseApi(typeof(BaseApi), type);
                            if (CheckInheritBaseApi)
                            {
                                listType.Add(type);
                            }
                        }

                    }
                }
                else if (typeClass == 2)
                {
                    foreach (Type type in dll.GetTypes())
                    {
                        if (type.Name.ToLower().StartsWith("sms"))
                        {
                            bool CheckInheritBaseApi = IsInheritBaseApi(typeof(SmsScript), type) ;
                            if (CheckInheritBaseApi)
                            {
                                listType.Add(type);
                            }
                        }

                    }
                }
                if (listType.Count > 0)
                {
                    foreach (Type obj in listType)
                    {
                        DescriptionClass des =getDescriptionClass(obj);

                        listDescription.Add(des);
                    }
                }
            }
            catch (Exception)
            {
            }
            return listDescription;
        }
        
        public static List<string> GetClasses()
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            return GetClasses(asm);
        }
        public static List<string> GetClassesSMS()
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            return GetClassesSMS(asm);
        }
        public static List<string> GetClassesSMS(Assembly asm)
        {
            List<string> classlist = new List<string>();
            foreach (Type type in asm.GetTypes())
            {
                if (type.Name.ToLower().StartsWith("bluesea") || type.Name.ToLower().StartsWith("partner") || type.Name.ToLower().StartsWith("sms"))
                {
                    bool CheckInheritBaseApi = IsInheritBaseApi(typeof(SmsScript), type);
                    if (CheckInheritBaseApi)
                    {
                        classlist.Add(type.Namespace + "." + type.Name);
                    }
                }
                //else if (type.Name.ToLower().StartsWith("partner"))
                //{
                //    bool CheckInheritBaseApi = IsInheritBaseApi(typeof(SmsScriptPartner), type);
                //    if (CheckInheritBaseApi)
                //    {
                //        classlist.Add(type.Namespace + "." + type.Name);
                //    }
                //}

            }

            return classlist;
        }
        public static List<string> GetClasses(Assembly asm)
        {
            List<string> classlist = new List<string>();
            foreach (Type type in asm.GetTypes())
            {
                if (type.Name.ToLower().EndsWith("api"))
                {
                    bool CheckInheritBaseApi = IsInheritBaseApi(typeof(BaseApi), type);
                    if (CheckInheritBaseApi)
                    {
                        classlist.Add(type.Namespace + "." + type.Name);
                    }
                }

            }

            return classlist;
        }
        public static bool IsInheritBaseApi(Type BaseType, Type type)
        {
            Type objType = typeof(object);
            //Type BaseType = Type.GetType("TuyennvLibrary.ServerApi.ClassApi.BaseApi");
            Type tempBaseType = type.BaseType;

            while (tempBaseType != BaseType && tempBaseType != objType && tempBaseType != null)
            {
                tempBaseType = tempBaseType.BaseType;
            }
            if (tempBaseType == objType)
                return false;
            if (tempBaseType == BaseType)
                return true;
            return false;
        }
        public static List<FileInfo> getFiles(string pathDir, string[] extention)
        {
            DirectoryInfo dir = new DirectoryInfo(pathDir);
            List<FileInfo> files = new List<FileInfo>();
            foreach (FileInfo f in dir.GetFiles())
            {
                foreach (string ext in extention)
                {
                    if (f.Extension.ToLower() == ext.ToLower())
                    {
                        files.Add(f);
                        break;
                    }
                }
            }
            return files;
        }
        /// <summary>
        /// Mã hóa MD5
        /// </summary>
        /// <param name="input">Chuỗi cần mã hóa</param>
        /// <returns></returns>
        public static string md5(string input)
        {
            MD5 md5Hash = MD5.Create();
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes 
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data  
            // and format each one as a hexadecimal string. 
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string. 
            return sBuilder.ToString();
        }
        /// <summary>
        /// Lấy source html của 1 url
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string getHtmlfrom(string url)
        {
            try
            {
                WebClient webclient = new WebClient();
                byte[] data = webclient.DownloadData(url);
                string html = Encoding.UTF8.GetString(data);
                html = HttpUtility.HtmlDecode(html);
                html = Regex.Replace(html, "\\s+", " ");
                return html;
            }
            catch (Exception)
            {
            }
            return string.Empty;
        }

       
        /// <summary>
        /// Lấy giá trị của key trong một json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="json"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T getValueJson<T>(string key, JObject json, T value)
        {
            object obj = null;

            try
            {
                obj = json[key];
                value = (T)obj;
            }
            catch (Exception)
            {
            }
            return value;
        }

        /// <summary>
        /// Lấy các giá trị trong message ở vị trí position qua từng dấu cách
        /// </summary>
        /// <param name="message">Nội dung tin nhắn</param>
        /// <param name="position">Vị trí cần lấy trong Message(tính từ 1, không tính command)</param>
        /// <returns></returns>
        public static string getContentEx(string message, int position)
        {
            try
            {
                message = Regex.Replace(message.Trim(), "\\s+", " ");
                return message.Split(' ')[position];
            }
            catch (Exception)
            {
            }
            return string.Empty;
        }
        /// <summary>
        /// Upload một file lên server
        /// </summary>
        /// <param name="fileUpload"></param>
        /// <param name="_allowedExtension">Loại extension của file (VD: .jpg , .gif)</param>
        /// <param name="pathDir">Đường dẫn tương đối</param>
        /// <param name="Server"></param>
        /// <returns></returns>
        public static string UploadFile(FileUpload fileUpload, string[] _allowedExtension, string pathDir, HttpServerUtility Server)
        {

            if (!fileUpload.HasFile)
                return string.Empty;
            pathDir = (!pathDir.StartsWith("/")) ? "/" + pathDir : pathDir;
            string fileExtension = System.IO.Path.GetExtension(fileUpload.FileName).ToLower();

            bool _allowedFile = false;

            for (int i = 0; i < _allowedExtension.Length; i++)
            {
                if (fileExtension == _allowedExtension[i])
                {
                    _allowedFile = true;
                    break;
                }
            }

            if (!_allowedFile)
                return String.Empty;

            string file = fileUpload.FileName.ToString();
            string fileName = Guid.NewGuid().ToString() + fileExtension;
            string fileend = ((pathDir.EndsWith("/")) ? pathDir : pathDir + "/") + file.Trim();
            string filePath = Server.MapPath(fileend.ToString());
            FileInfo f = new FileInfo(filePath);
            if (f.Exists)
            {
                f.Delete();
            }
            fileUpload.PostedFile.SaveAs(filePath);

            return file.Trim();
        }
        /// <summary>
        /// Lấy giá trị x trong đầu số AxBC
        /// </summary>
        /// <param name="serviceid">Đầu số dịch vụ</param>
        /// <returns></returns>
        public static string getXofServiceId(string serviceid)
        {
            return serviceid[1].ToString();
        }
        public static string getSuccessMessage(string message)
        {
            message = "<font style=\"color: Blue; font-size: 14px; font-weight: bold\">" + message + "</font>";
            return message;
        }
        public static string getErrorMessage(string message)
        {
            message = "<font style=\"color: Red; font-size: 14px; font-weight: bold\">" + message + "</font>";
            return message;
        }
        public static string MapPath(HttpServerUtility Server, string pathFolder)
        {
            return Server.MapPath(pathFolder).Replace("administrator\\", "");
        }
        public static bool logError(TypeError type_error, string content)
        {
            ErrorLogModel errorlogModel = new ErrorLogModel();
            ErrorLog error = new ErrorLog();
            error.type_error = (int)type_error;
            error.content = content;
            return errorlogModel.Insert(error);
        }
        /// <summary>
        /// Ghi lỗi cho các kịch bản SMS
        /// </summary>
        /// <param name="command">Mã SMS nhận được</param>
        /// <param name="people">Tên đầy đủ người ghi log lỗi</param>
        /// <param name="content">Nội dung lỗi</param>
        /// <returns></returns>
        public static bool logErrorSMS(string command, string people, string content)
        {
            content = string.Format("command: {0} - people: {1} - info: {2}", command, people, content);
            return logError(TypeError.Sms, content);
        }
        /// <summary>
        /// Ghi lỗi cho các kịch bản API
        /// </summary>
        /// <param name="classapi">Tên class API đang sử dụng</param>
        /// <param name="people">Tên đầy đủ người ghi log lỗi</param>
        /// <param name="content">Nội dung lỗi</param>
        /// <returns></returns>
        public static bool logErrorAPI(string classapi, string people, string content)
        {
            content = string.Format("class: {0} - people: {1} - info: {2}", classapi, people, content);
            return logError(TypeError.Api, content);
        }
        public static void WriteLog(String message)
        {
            FileStream _stream;
            try
            {
                String Path = Config.Server.MapPath("~/") + "BlueseaLog\\" + string.Format("{0:yyyy-MM-dd}", DateTime.Now) + ".txt";
                //String Path = HttpContext.Current.Server.MapPath("~/") + "200302.txt";
                if (!File.Exists(Path))
                    _stream = File.Create(Path);
                else
                    _stream = new FileStream(Path, FileMode.Append);

                StreamWriter sw = new StreamWriter(_stream);

                sw.WriteLine(DateTime.Now.ToString() + ":" + message + Environment.NewLine);
                //sw.Flush();
                sw.Close();
                sw.Dispose();
                _stream.Close();
                _stream.Dispose();
            }
            catch (Exception ex)
            {
                throw;
            }
        }

    }
}